home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 1
/
Nebula One.iso
/
Utilities
/
Unix
/
satan-1.1.1
/
perl
/
hosttype.pl
< prev
next >
Wrap
Text File
|
1995-04-10
|
5KB
|
191 lines
#
# infer_hosttype - classify host by banner, the dns HINFO record may be wrong.
# Output to:
#
# $hosttype{$target} operating system type per host
# $sysclass{$type} OS class that an OS type belongs to
# $hosttype_flag (*)
# $systype_counts{type} number of hosts per OS type
# $systype_severities{type} ditto, with at least one vulnerability
# $sysclass_counts{class} number of hosts per OS class
# $sysclass_severities{class} ditto, with at least one vulnerability
# $hosts_by_systype{type} string with hosts per OS type
# $systypes_by_class{class} string with OS types per OS class
#
# (*) Is reset whenever the $hosttype etc. tables are updated. To recalculate,
# invoke make_hosttype_info_flag().
#
# Standalone usage: perl hosttype.pl [satan_record_files...]
#
$hosttype_files = "rules/hosttype";
$hosttype_unknown = "unknown type";
$hosttype_notprobed = "not scanned";
sub build_infer_hosttype {
local($files) = @_;
local($type, $code, $file, $cond, $type, $class);
$code = "sub infer_hosttype {\n";
$code .= "\tlocal(\$type);\n";
$code .= "\tif (\$service !~ /^(smtp|telnet|ftp)\$/) {\n\t\treturn;\n\t}\n";
$class = "other";
foreach $file (split(/\s+/, $files)) {
open(RULES, $file) || die "cannot open $file: $!";
while (<RULES>) {
chop;
while (/\\$/) {
chop;
$_ .= <RULES>;
chop;
}
s/#.*$//;
s/\s+$//;
next if /^$/;
if (/^CLASS\s+(.+)/i) {
$class = $1;
} else {
s/\bUNKNOWN\b/(HOSTTYPE eq "" || HOSTTYPE eq \"$hosttype_unknown\" || HOSTTYPE eq \"$hosttype_notprobed\")/;
s/\bHOSTTYPE\b/\$hosttype{\$target}/g;
s/@/\\@/g;
($cond, $type) = split(/\t+/, $_, 2);
$type = "\$1" if ($type eq "");
$code .= "\
if ($cond) {
\$type = $type;
\$hosttype{\$target} = \$type;
\$sysclass{\$type} = \"$class\";
\$hosttype_flag = 0;
return;
}
";
}
}
close(RULES);
}
$code .= "\t\$hosttype{\$target} = \"\"
if !exists(\$hosttype{\$target});\n}";
return $code;
}
#
# Generate hosttype-dependent statistics.
#
sub make_hosttype_info {
local($host, $class, $type, $count);
if ($hosttype_flag > 0) {
return;
}
$hosttype_flag = time();
print "Rebuild host type statistics...\n" if $debug;
&make_severity_info();
%hosts_by_systype = ();
%systypes_by_class = ();
%systype_severities = ();
%systype_counts = ();
%sysclass_severities = ();
%sysclass_counts = ();
for $host (keys %all_hosts) {
$hosttype{$host} = $hosttype_unknown
if ($host && $hosttype{$host} eq "" && &get_host_time($host) > 1);
$hosttype{$host} = $hosttype_notprobed
if ($host && $hosttype{$host} eq "");
}
$sysclass{$hosttype_unknown} = "other";
$sysclass{$hosttype_notprobed} = "other";
for $type (sort keys %sysclass) {
$systype_severities{$type} = 0;
$sysclass_severities{$sysclass{$type}} = 0;
}
for $host (sort keys %hosttype) {
$type = $hosttype{$host};
if ($type eq "") {
$type = $hosttype{$host} = $hosttype_unknown;
}
if (exists($severity_host_type_info{$host})) {
$systype_severities{$type}++;
}
$hosts_by_systype{$type} .= $host . "\n";
$systype_counts{$type}++;
}
for $type (sort keys %sysclass) {
if (($count = $systype_counts{$type}) > 0) {
$class = $sysclass{$type};
$systypes_by_class{$class} .= $type . "\n";
$sysclass_counts{$class} += $count;
if ($systype_severities{$type}) {
$sysclass_severities{$class} += $systype_severities{$type};
}
} else {
delete($sysclass{$type});
}
}
}
#
# Reset the host type tables.
#
sub clear_hosttype_info {
%hosttype = ();
%systype = ();
%hosts_by_systype = ();
%systypes_by_class = ();
%systype_severities = ();
%systype_counts = ();
%sysclass_severities = ();
%sysclass_counts = ();
$hosttype_flag = 0;
}
#
# Some scaffolding for stand-alone operation
#
if ($running_under_satan) {
eval &build_infer_hosttype($hosttype_files);
die "error in $hosttype_files: $@" if $@;
} else {
$running_under_satan = -1;
$debug = 1;
require 'perl/misc.pl';
#
# Generate code from rules files.
#
$code = &build_infer_hosttype($hosttype_files);
print "Code generated from $hosttype_files:\n\n";
print $code;
eval $code;
die "error in $hosttype_files: $@" if $@;
#
# Apply rules.
#
print "\nApplying rules to all SATAN records...\n";
while (<>) {
chop;
if (&satan_split($_) == 0) {
&infer_hosttype();
}
}
&make_hosttype_info();
for (sort keys %hosttype) {
print "$hosttype{$_} $_\n";
}
print "Host class information:\n";
for $class (sort keys %systypes_by_class) {
print "$class ";
print join(' ', split(/\n/, $systypes_by_class{$class}));
print "\n";
}
}
1;